/*
 * OccurrencePattern.cpp
 *
 * Copyright 2012 Fabian Wenzelmann
 *
 * This file is part of Recognition-Procedures-for-Boolean-Functions.
 *
 * Recognition-Procedures-for-Boolean-Functions is free software: you
 * can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * Recognition-Procedures-for-Boolean-Functions is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Recognition-Procedures-for-Boolean-Functions.
 *
 * If not, see <http://www.gnu.org/licenses/>.
 */

#include "bfr/OccurrencePattern.hpp"

#include <string>
#include <sstream>
#include <iostream>
#include <set>

namespace bfr {

OccurrencePattern::OccurrencePattern(size_t vID)
    : variableID(vID), elements() { }

OccurrencePattern::OccurrencePattern(size_t vID, size_t initialSize)
    : variableID(vID), elements() { }

OccurrencePattern::OccurrencePattern(const OccurrencePattern &other)
    : variableID(other.variableID), elements(other.elements) { }

OccurrencePattern::~OccurrencePattern() { }

OccurrencePattern::const_iterator OccurrencePattern::begin() const {
    return elements.begin();
}

OccurrencePattern::const_iterator OccurrencePattern::end() const {
    return elements.end();
}

void OccurrencePattern::addOccurrence(size_t variableCount) {
    elements.insert(variableCount);
}

size_t OccurrencePattern::size() const {
    return elements.size();
}

size_t OccurrencePattern::getVariableId() const {
    return variableID;
}

short OccurrencePattern::compare(const OccurrencePattern &other) const {
    const_iterator m1 = begin();
    const_iterator m2 = other.begin();

    const_iterator end1 = end();
    const_iterator end2 = other.end();

    while (m1 != end1 && m2 != end2) {
        size_t next1 = *m1;
        size_t next2 = *m2;

        if (next2 < next1) {
            return -1;
        }
        else if (next1 < next2) {
            return 1;
        }

        m1++;
        m2++;
    }
    if (m1 != end1) {
        return 1;
    }
    if (m2 != end2) {
        return -1;
    }
    return 0;
}

bool OccurrencePattern::operator ==(const OccurrencePattern &other) const {
    return compare(other) == 0;
}

bool OccurrencePattern::operator !=(const OccurrencePattern &other) const {
    return compare(other) != 0;
}

bool OccurrencePattern::operator <(const OccurrencePattern &other) const {
    return compare(other) < 0;
}

bool OccurrencePattern::operator >(const OccurrencePattern &other) const {
    return compare(other) > 0;
}

bool OccurrencePattern::operator <=(const OccurrencePattern &other) const {
    return compare(other) <= 0;
}

bool OccurrencePattern::operator >=(const OccurrencePattern &other) const {
    return compare(other) >= 0;
}

std::string OccurrencePattern::asString() const {
    std::ostringstream stream;
    stream << *this;
    return stream.str();
}

}
